<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Waveform Chart</title>
  <style>
    canvas {
      border: 1px solid black;
    }
  </style>
</head>
<body>
<div id="main" style="width: 1200px;height:800px;"></div>
<button type="button" onclick="stopInterval()">停止</button>
<button type="button" onclick="startInterval()">开始</button>
<script src="https://cdn.bootcdn.net/ajax/libs/mqtt/4.1.0/mqtt.min.js"></script>
<script src="https://cdn.bootcss.com/echarts/4.2.1-rc1/echarts.min.js"></script>
<!--<script src="data.js"></script>-->
<!--<script src="chartsData.js"></script>-->
<script src="adata.js"></script>
<script src="mqtt.js"></script>
<script type="text/javascript">
  // const size = adata[1].length
  let param = {
    mb_h: [],
    mb_l: [],
    jy_h: [],
    jy_l: [],
    xData: new Array(1201).fill(''),
    mb: new Array(1201).fill(null),
    _mb: new Array(1201).fill(null),
    jy: new Array(1201).fill(null),
    currentIndex: 1,
    size: 0,
    intervalFlag: false,
    speed:20,
    peaks:[],
    _peaks:[],
    max: 2933.8,
    initTitle:'脉率：   ，波长：  ms， 波幅：',
  }

   adata[1].forEach(([first, second, third, fourth]) => {
     param.jy_l.push(first)
     param.jy_h.push(second)
     param.mb_l.push(third)
     param.mb_h.push(fourth)
   })
  var echartsOption = {
    title: {
      text: param.initTitle,
      left: 'center', // 水平居中
      top: '10%',       // 放在最顶部
      textStyle:{
        color: '#ff0000' // 设置文字颜色为红色
      }
    },
    color: ['#428DF9', '#95CEF3'],
    tooltip: {
      trigger: 'axis',
      formatter: function(t) {
        if (t) {
          let e = ''
          e += t[0].name.replace(/\-/g, '/') + '<br/>'
          for (let n = 0; n < t.length; n++) {
            const o = t[n]
            e += '<div>',
              e += '<span style="margin-right:5px;display:inline-block;width:10px;height:10px;border-radius:5px;background-color:' + o.color + ';"></span>',
              e += o.seriesName + '\uff1a' + o.value,
              e += '</div>'
          }
          return e
        }
      },
      backgroundColor: '#ccc',
      borderWidth: 1,
      borderColor: '#ccc',
      padding: 10,
      textStyle: {
        color: '#000',
        fontSize: 12,
        align: 'left'
      }
    },
    legend: {
      show: !0,
      x: 'center',
      y: '10px',
      data: [{
        name: '脉搏/强度&脉率',
        textStyle: {
          color: '#428DF9'
        }
      }, {
        name: '静压/深度',
        textStyle: {
          color: '#95CEF3'
        }
      }]
    },
    xAxis: {
      type: 'category',
      scale: !0,
      data: param.xData,
      axisTick: {
        alignWithLabel: !0
      },
      axisLine: {
        onZero: !1,
        lineStyle: {
          color: '#01efef'
        }
      },
      axisLabel: {
        textStyle: {
          color: '#01efef'
        }
      }
    },
    yAxis: [{
      type: 'value',
      name: '脉搏/强度&脉率',
      nameLocation: 'center',
      nameGap: 30,
      nameTextStyle: {
        color: '#428DF9'
      },
      axisLabel: {
        color: '#428DF9'
      },
      calculateMinMax: true,
     // inverse: false, // 确保刻度顺序正确
      min: function(t) {
        return -3000   //-600
      },
      max: function(t) {
        return 3000     //600
      },
      splitLine: {
        show: !1
      }
    }, {
      type: 'value',
      name: '静压/深度',
      nameLocation: 'center',
      nameGap: 48,
      nameTextStyle: {
        color: '#95CEF3'
      },
      axisLabel: {
        color: '#95CEF3'
      },
      calculateMinMax: true,
      // inverse: false, // 确保刻度顺序正确

      min: function(t) {
        return 9000   //-600
      },
      max: function(t) {
        return 16000     //600
      },
      splitLine: {
        show: !1
      }
    }],
    series: [param.mb, param.jy].map((e, n) => ({
      name: n === 0 ? '脉搏/强度&脉率' : '静压/深度',
      data: e,
      type: 'line',
      symbol: 'none',
      smooth: !0,
      yAxisIndex: n
    }))
  }
  var myChart = echarts.init(document.getElementById('main'))
  myChart.getZr().on('dblclick', params => {
    console.log('双击事件触发')
    if (param.intervalFlag) {
      stopInterval()
    } else {
      startInterval()
    }
  })
  // 使用刚指定的配置项和数据显示图表。
  myChart.setOption(echartsOption)

  let interval
  startInterval()
  function getAndRemoveLeftNElements(arr, n) {
    if (!arr || arr.length === 0) return [];

    // 限制 n 的范围，防止超出数组长度
    n = Math.min(n, arr.length);

    // 使用 splice 方法删除并返回前 n 个元素
    const removedElements = arr.splice(0, n);

    return removedElements;
  }
  function startInterval() {
    interval = setInterval(() => {
      param.mb.splice(0,param.speed)
      param._mb.splice(0,param.speed)
      param.jy.splice(0,param.speed)
      param.xData.splice(0,param.speed)
      if (param.mb_l.length > 0) {
        let c_mb_l = getAndRemoveLeftNElements(param.mb_l,param.speed)
        let c_mb_h = getAndRemoveLeftNElements(param.mb_h,param.speed)
        let c_jy_l = getAndRemoveLeftNElements(param.jy_l,param.speed)
        let c_jy_h = getAndRemoveLeftNElements(param.jy_h,param.speed)

        c_mb_l.forEach((value,index)=>{
          param.mb.push(int16Overflow(value + 256 * c_mb_h[index]) / 10)
          param._mb.push(-(int16Overflow(value + 256 * c_mb_h[index]) / 10))
          param.jy.push(int16Overflow(c_jy_l[index] + 256 *c_jy_h[index]) * 10)

        })
        param.peak = findPeaks(param.mb, 100,200,param.max);
        param._peak = findPeaks(param._mb, 100,200,param.max);
        // param.title = String.format("mailv "+ Math.round(60 * 1000.0 / (peak.get(1) - peak.get(0)) / 5)+" bochang: "+(peak.get(1) - peak.get(0)) * 5+" ms bofu "+  Math.floor(mb.get(peak.get(0)) - mb.get(_peak.get(0))));
        if(param.peak.length>=2){
          param.title = "脉率: "+ Math.round(60 * 1000.0 / (param.peak[1] - param.peak[0]) / 5)+", 波长: "+(param.peak[1] - param.peak[0]) * 5+" ms , 波幅： "+  Math.floor(param.mb[param.peak[0]] - param.mb[param._peak[0]])
        }else {
          param.title=param.initTitle
        }

      }else {
        param.title=param.initTitle
      }
      Array.from({length: 20}, (_, i) => {
        // 在此处处理每一个值 i
        console.log(i); // 例如，打印每个值
        param.xData.push((0.005 * param.currentIndex).toFixed(3) + 's')
        param.currentIndex++
      });
      myChart.setOption({
        series: [param.mb, param.jy].map((e, n) => ({
          data: e
        })),
        xAxis: {
          data: param.xData
        },
        title: {
          text: param.title
        },
      })
      param.intervalFlag = true
    }, 100)
  }

  function findPeaks(data, minDistance, minHeight, maxHeight) {
    const peaks = [];

    // 检查输入的有效性
    if (!Array.isArray(data) || data.length < 2 * minDistance + 1) {
      throw new Error("Data array is too short or not an array.");
    }

    // 初始化前一个最大值
    let prevValue = data[0];
    let prevIndex = 0;

    for (let i = 1; i < data.length; i++) {
      if (data[i] === null || data[i] === undefined) continue;
      if (data[i] > prevValue) {
        // 如果当前值大于前一个值，则可能是一个上升趋势
        prevValue = data[i];
        prevIndex = i;
      } else if (data[i] < prevValue) {
        // 如果当前值小于前一个值，检查前一个值是否为局部最大值
        if (i - prevIndex >= minDistance && prevValue >= minHeight && prevValue <= maxHeight) {
          peaks.push(prevIndex);
          prevValue = data[i];
          prevIndex = i;
        }
      }
      // 注意：原Java代码中有注释掉的部分处理连续相同值的情况，这里我们省略了这个部分，
      // 因为它被注释掉了，并且在大多数情况下不需要处理连续相同的值。
    }

    // 检查最后一个可能的峰值
    if (prevValue >= minHeight && prevValue <= maxHeight && data.length - 1 - prevIndex >= minDistance) {
      peaks.push(prevIndex);
    }

    return peaks;
  }
  function int16Overflow(num) {
    let result = num & 0xFFFF // 使用按位与运算符将数字限制在16位范围内
    if (result > 32767) { // 如果结果大于32767（int16的最大值）
      result -= 65536 // 减去65536以实现溢出
    } else if (result < -32768) { // 如果结果小于-32768（int16的最小值）
      result += 65536 // 加上65536以实现溢出
    }
    return result
  }


  function stopInterval() {
    clearInterval(interval)
    param.intervalFlag = false
  }

</script>
</body>
</html>
